﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.DirectoryServices;

namespace ViVa.ActiveDirectory
{
    public class ADService
    {
        public static ActiveDirectory GetAuthentication()
        {
            var AD = new ActiveDirectory("",
                ConfigurationManager.AppSettings["ADUsername"],
                ConfigurationManager.AppSettings["ADPassword"],
                ConfigurationManager.AppSettings["LDAPRoot"]);
            return AD;
        }

        public static ADEntry GetUserBySamAccountName(string samAccountName)
        {
            var AD = GetAuthentication();
            return AD.GetUserList(string.Format("(&(objectClass=User)(objectCategory=Person)(SamAccountName={0}))", samAccountName)).FirstOrDefault();
        }

        public static ADEntry GetUserByDistinguishedName(string DN)
        {
            var AD = GetAuthentication();
            return AD.GetUserList(string.Format("distinguishedName={0}", DN)).FirstOrDefault();
        }
        

        public static List<ADEntry> GetUsers(string usernameFilter)
        {
            var AD = GetAuthentication();
            return AD.GetUserList(string.Format("(&(objectClass=User)(objectCategory=Person)(| (CN=*{0}*)(SamAccountName=*{0}*)))", usernameFilter));
        }
        
        /// <summary>
        /// Save changes to the user. Note: Not all properties are changeble; This is not catched.
        /// </summary>
        /// <param name="adEntry"></param>
        public static void Save(ADEntry adEntry, bool SaveIfEmpty = false)
        {
            var AD = GetAuthentication();
            AD.Save(adEntry);
        }

        public static void ChangeUserPassword(ADEntry adEntry, string passWord)
        {
            var AD = GetAuthentication();
            AD.ChangeUserPassword(adEntry, passWord);
        }


        public static List<ADGroup> GetGroups(string groupFilter, bool getMembers = true)
        {
            var AD = GetAuthentication();
            return AD.GetGroupList(string.Format("(&(objectClass=Group)(objectCategory=Group)(| (DN=*{0}*)(CN=*{0}*)))", groupFilter), getMembers);
        }

        public static ADGroup GetGroupByDistinguishedName(string DN)
        {
            var AD = GetAuthentication();
            return AD.GetGroupList(string.Format("distinguishedName={0}", DN)).FirstOrDefault();
        }

        public static void RemoveGroups(List<string> groupDNList, ADEntry userObject)
        {
            var AD = GetAuthentication();
            var userObj = GetUserBySamAccountName(userObject.SamAccountName);            
            foreach (string groupDN in groupDNList)
            {
                AD.RemoveUserFromGroup(userObj, GetGroupByDistinguishedName(groupDN));
            }
        }

        public static void AddGroups(List<string> groupDNList, ADEntry userObject)
        {
            var AD = GetAuthentication();
            var userObj = GetUserBySamAccountName(userObject.SamAccountName);
            foreach (string groupDN in groupDNList)
            {
                var group = GetGroupByDistinguishedName(groupDN);
                if (!AD.isUserMemberof(userObj, group))
                {
                    AD.AddUserToGroup(userObj, group);
                }
            }
        }


    }
}